/* Filename: snder.c
 * Description: 报式socket数据包变长
 * Last modified: humble 2020-06-14 19:05
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "proto.h"

#define IPSTRSIZE (40)

static void usage(void);

int main(int argc, char **argv)
{
    int sd;
    int size;
    struct sockaddr_in /*laddr,*/raddr;
    struct msg_st *sbufp;
    socklen_t raddr_len;
    char ipstr[IPSTRSIZE];

    if(argc != 3){ fprintf(stderr, "argc !=3"); usage(); exit(1); }

    if(strlen(argv[2]) > NAMEMAX){ fprintf(stderr, "NAME too long\n"); usage(); exit(1); }

    size = sizeof(struct msg_st) + strlen(argv[2]);
    sbufp = malloc(size);
    if(!sbufp){ perror("malloc()"); exit(1); }

    sd = socket(AF_INET, SOCK_DGRAM, 0/*IPPROTO_UDP*/);
    if(sd < 0){ perror("socket()"); exit(1); }

    /* 发送方可省略bind
    laddr.sin_family = AF_INET;
    laddr.sin_port = htons(atoi(RCVPORT));
    inet_pton(AF_INET, "0.0.0.0", &laddr.sin_addr);

    if(bind(sd, (void *)&laddr, sizeof(laddr)) < 0){ perror("bind()"); exit(1); }
    */

    memset(sbufp, 0, size);
    strcpy(sbufp->name, argv[2]);
    sbufp->math = htonl(rand() % 100);
    sbufp->chinese = htonl(rand() % 100);

    raddr.sin_family = AF_INET;
    raddr.sin_port = htons(atoi(RCVPORT));
    inet_pton(AF_INET, argv[1], &raddr.sin_addr);

    //发送放的sendto函数不用回填raddr_len
    /* 重要：若没初始化该值，则会导致第一次收到数据出错 */
    //raddr_len = sizeof(raddr);

    if(sendto(sd, sbufp, size, 0, (void *)&raddr, sizeof(raddr)) < 0){
        perror("sendto()");
        exit(1);
    }

    puts("ok!");

    close(sd);
    return 0;
}

static void usage(void)
{
#define USAGE "Usage:\n\
  ./snder <IP> <NAME>\n"
    printf(USAGE);
}
